from google.appengine.ext import db
from google.appengine.api import users

# A chapter of a book of a translation of the Bible.
# The book attribute runs from 1 ... 66 for the Bible's books (not likely to change! - we aren't supporting apocrypha...)

class Chapter(db.Model):
    translation = db.StringProperty(multiline=False) # Which translation this is from. E.g. "KJV"
    bookno = db.IntegerProperty()                    # Which book 1..66 values, is this chapter from
    chapno = db.IntegerProperty()                    # Which chapter of the book is this
    versescount = db.IntegerProperty()               # How many verses does this chapter have (just for sanity checks of later verses range quotes)
    content = db.TextProperty()                      # All the verses as a single slab, with <v> tags decorating the verse numbers
# Ok. I'm scrapping this date field, since it makes bulk uploading harder. It was never going to be of great interest anyway!
#    date = db.DateTimeProperty(auto_now_add=True)    # When was this Chapter added - just to make it easier to check for successful uploading etc. Needed??

#Fairly constant across tranlations in the same language (oxymoron?!), but something like this is needed anyway.
class Book(db.Model):
    translation = db.StringProperty(multiline=False) # Which translation this is from. E.g. "KJV"
    bookno = db.IntegerProperty()                    # Which book 1..66 values, is this
    bookname = db.StringProperty(multiline=False)    # Name of the book in this translation
    chapcount = db.IntegerProperty()                 # How many chapters in the book


# Person. Represents the identity of a user. Links to all their bookmarks; and their notes (and eventually study groups)
class Person(db.Model):
    user = db.UserProperty()                       # Identity of this person
    name = db.StringProperty(multiline=False)      # Unique name for the user (their "roman name"!)
    nick = db.StringProperty(multiline=False)      # Nickname for the user (for use in study groups - not necessarily unique!)
    lasttrans = db.StringProperty(multiline=False) # Which translation did they last use?
    lastread = db.IntegerProperty()                # Which number note is this - by THIS author! (Not globally unique no!) 
    automarks = db.ListProperty(int)	           # List of length 66, contains the most recently view chap of the corresponding (bookno-1)
    opusno = db.IntegerProperty()                  # How many notes have been written by this user
    groups = db.ListProperty(db.Key)               # NB! This is the list of keys of groups the Person is a member of.
    # Implicit bookmarks property, via ReferenceProperty in Mark()


# Notes. Represents a note or annotation that refers to a (portion) of the chapter it attaches to.
# LIMITATION: really does not support notes that relate to a passage other than a (subset) of a chapter
class Note(db.Model):
#    author = db.StringProperty(multiline=False)      # Which user wrote this!
    author = db.UserProperty()                       # Which user wrote this!
    shared = db.IntegerProperty()                    # 0 or null means not share. Else it might be an id of a group or something. Not used yet...
    opusno = db.IntegerProperty()                    # Which number note is this - by THIS author! (Not globally unique no!) Don't reuse deletions
    bookno = db.IntegerProperty()                    # Which book 1..66 values, is this note for 
    chapno = db.IntegerProperty()                    # Which chapter of the book is this note for
    start = db.IntegerProperty()                    # Which verse is the start for the passage this note is about
    finish = db.IntegerProperty()                    # Which verse is the (inclusive) finish for the passage this note is about
    extent = db.IntegerProperty()                   #A synthetic property, so that we can order notes so that early and then more extensive (in bible
                                   # ... passage length) notes come earliest. Given no chapter >= 1000 verses, define extent=(start*1000)-finish
    content = db.TextProperty()                      # The actual note contents
    date = db.DateTimeProperty(auto_now_add=True)    # This is important, since we want users to know when they wrote what!


# (Manual) Bookmark. I guess we will have a few. Not quite sure how it will fit in with the Person bit.
# TODO: It is actually interesting that the Mark is very similar to a Note. Could I conflate them somehow?? Poly etc.? Ignore for now!!
class Mark(db.Model):
    name = db.StringProperty(multiline=False)      # Bookmarks might have a name. We might use it to partly encode the "colour" etc.
    owner = db.ReferenceProperty(Person,
                                   collection_name='bookmarks')
    bookno = db.IntegerProperty()                    # Which book 1..66 values, is this note for 
    chapno = db.IntegerProperty()                    # Which chapter of the book is this note for
    date = db.DateTimeProperty(auto_now_add=True)    # This is important, since we want users to know when they wrote what!


# Groups. May need expanding. But allows many-many with Persons
class Group(db.Model):
    name = db.StringProperty(multiline=False)      # Name of the group
    admin = db.UserProperty()                      # ID of the administrator of the group

    # Find all the people who's groups list equals self.key.
    def members(self):
        return Person.all().filter("groups =", self.key())


